<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台（PHP版）
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码，建议反馈是我们前进的动力
// | 开源版本可自由商用，可去除界面版权logo
// | gitee下载：https://gitee.com/likeshop_gitee/likeadmin
// | github下载：https://github.com/likeshop-github/likeadmin
// | 访问官网：https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------

namespace app\api\lists;


use app\common\cache\UserTokenCache;
use app\common\lists\ListsExcelInterface;
use app\common\lists\ListsExtendInterface;
use app\common\model\finance\TransactionRecord;
use app\common\model\user\User;
use app\common\model\card\Card;
use app\common\lists\ListsSearchInterface;


/**
 * transaction列表
 * Class TransactionRecordLists
 * @package app\api\lists
 */
class TransactionRecordLists extends BaseApiDataLists implements ListsSearchInterface, ListsExcelInterface, ListsExtendInterface
{


    /**
     * @notes 设置搜索条件
     * @return \string[][]
     * @author likeadmin
     * @date 2025/04/09 14:11
     */
    public function setSearch(): array
    {
        return [
            '=' => ['card_no', 'user_id', 'card_id', 'status', 'create_time_start', 'create_time_end'],
        ];
    }

    public function queryWhere()
    {
        // 指定用户
        $where[] = ['t.group_id', '=', $this->userInfo['group_id']];

        //运营
        if (isset($this->params['user_id']) && $this->params['user_id']) {
            $where['t.user_id'] = $this->params['user_id'];
        }

        // 卡号
        if (isset($this->params['card_id']) && $this->params['card_id']) {
            if (strlen($this->params['card_id']) == 4) {
                $where[] = function ($query) {
                    $query->whereRaw('RIGHT(t.masked_card_number, 4) = ?', [$this->params['card_id']]);
                };
            } else {
                $where[] = ['t.card_id', '=', $this->params['card_id']];
            }
        }

        //卡类型
        if (isset($this->params['card_bin']) && $this->params['card_bin']) {
            $where[] = ['t.card_bin', '=', $this->params['card_bin']];
        }

        // 开始时间
        if (isset($this->params['create_time_start']) && isset($this->params['create_time_end']) && $this->params['create_time_start'] && $this->params['create_time_end']) {
            $where[] = [
                't.transaction_date', 'between', [$this->params['create_time_start'], $this->params['create_time_end']]
            ];
        }

        //卡别名
        if (isset($this->params['alias']) && $this->params['alias']) {
            $where[] = ['c.alias', 'like', '%' . $this->params['alias'] . '%'];
        }

        // 交易状态
        if (isset($this->params['status']) && $this->params['status']) {
            $status = ['APPROVED', 'FAILED', 'PENDING', 'SUCCESS'];
            if ($this->params['status'] == 'OTHER') {
                $where[] = ['t.status', 'not in', $status];

            } else {
                $where[] = ['t.status', '=', $this->params['status']];
            }

        }

        // 卡组查询
        if (isset($this->params['card_group_id']) && $this->params['card_group_id']) {
            $where[] = ['c.card_group_id', '=', $this->params['card_group_id']];
        }

        //交易类型
        if (isset($this->params['transaction_type']) && $this->params['transaction_type']) {
            $transaction_type = ['AUTHORIZATION', 'CLEARING', 'REVERSAL'];
            if ($this->params['transaction_type'] == 'OTHER') {
                $where[] = ['t.transaction_type', 'not in', $transaction_type];
            } else {
                $where[] = ['t.transaction_type', '=', $this->params['transaction_type']];
            }

        }

        //商户类型
        if (isset($this->params['merchant_name']) && $this->params['merchant_name']) {
            $where[] = ['t.merchant_name', 'like', '%' . $this->params['merchant_name'] . '%'];
        }


        return $where;
    }

    /**
     * @notes 获取transaction列表
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @author likeadmin
     * @date 2025/04/09 14:11
     */
    public function lists(): array
    {
        // 如果从请求中获取失败，尝试从其他来源获取
        if (empty($this->userInfo) && !empty($this->request->header('token'))) {
            $userInfo = (new UserTokenCache())->getUserInfo($this->request->header('token'));
            if ($userInfo) {
                $this->userInfo = $userInfo;
                $this->userId = $userInfo['user_id'] ?? 0;
            }
        }
        $field = ['u.account', 'u.leader_account', 'c.alias', 'c.card_group_id', 't.transaction_id', 't.transaction_type', 't.user_id', 't.group_id', 't.card_id',
            't.masked_card_number', 't.service_fee', 't.service_amount', 't.billing_amount', 't.billing_currency', 't.status', 't.merchant_name',
            't.failure_reason', 't.transaction_date', 't.card_bin', 't.smallamount', 'transaction_amount', 'transaction_currency', 'location_country', 'outbinservice'];

        $list = TransactionRecord::alias('t')
            ->join('user u', 't.user_id = u.id')
            ->join('card c', 't.card_id=c.card_id')
            ->where($this->queryWhere())
            ->field($field)
//            ->where([
//                't.group_id' => $this->userInfo['group_id'],
//            ])
            ->limit($this->limitOffset, $this->limitLength)
            ->order(['transaction_date' => 'desc'])
            ->select()
            ->toArray();

        // 修改billing_amount
        //  foreach ($list as &$item) {
        //    $item['billing_amount'] = abs(floatval($item['billing_amount'])) + abs(floatval($item['service_amount']));
        //}

        foreach ($list as &$item) {
            // 时区转换处理 - 只有在明确指定时区时才转换
            if (isset($this->params['timezone']) && !empty($this->params['timezone'])) {
                try {
                    $utcTime = new \DateTime($item['transaction_date'], new \DateTimeZone('UTC'));
                    $utcTime->setTimezone(new \DateTimeZone($this->params['timezone']));
                    $item['transaction_date'] = $utcTime->format('Y-m-d H:i:s');
                } catch (\Exception $e) {
                    $item['transaction_date'] = $item['transaction_date'];
                }
            }
            //交易记录状态和类型为退款时，不显示给商户端 2025-08-30
//            if ($item['transaction_type'] == 'refund') $item['transaction_type'] = '';
//            if ($item['status'] == 'REFUNDED') $item['status'] = '';
        }
        unset($item);


        return $list;
    }

    /**
     * @notes 扩展字段，统计交易金额
     * @return array
     */
    public function extend()
    {
        // 交易记录总金额
        $billing_amount = TransactionRecord::alias('t')
            ->join('user u', 't.user_id = u.id')
            ->join('card c', 't.card_id=c.card_id')
            ->where($this->queryWhere())
            ->whereIn('t.transaction_type', [
                'CARD_PAYMENT', 'CLEARING', 'settled', 'pending', 'AUTHORIZATION', 'WAITING_CLEARANCE'
            ])
            ->whereRaw("RTRIM(LTRIM(t.status)) IN ('SUCCESS', 'settled', 'posted', 'pending', 'CARD_PAYMENT', 'WAITING_CLEARANCE')")
            ->sum(\think\facade\Db::raw('ABS(t.billing_amount)'));

        return ['billing_amount' => $billing_amount];
    }

    /**
     * @notes 获取transaction数量
     * @return int
     * @date 2025/04/09 14:11
     */
    public function count(): int
    {
        // 如果从请求中获取失败，尝试从其他来源获取
        if (empty($this->userInfo) && !empty($this->request->header('token'))) {
            $userInfo = (new UserTokenCache())->getUserInfo($this->request->header('token'));
            if ($userInfo) {
                $this->userInfo = $userInfo;
                $this->userId = $userInfo['user_id'] ?? 0;
            }
        }

        return TransactionRecord::alias('t')
            ->join('user u', 't.user_id = u.id')
            ->join('card c', 't.card_id=c.card_id')
            ->where($this->queryWhere())
            ->count();
    }

    public function setFileName(): string
    {
        return '交易记录';
    }

    /**
     * @notes 导出字段
     * @return string[]
     * @date 2022/11/24 16:17
     */
    public function setExcelFields(): array
    {
        return [
            'transaction_date' => '交易时间',
            'transaction_id' => '交易id',
            // 'card_id' => 'card_ID',
            'masked_card_number' => '卡号',
            'alias' => '别名',
            'leader_account' => '组长',
            'account' => '运营',
            'merchant_name' => '商户',
            'billing_amount' => '账单金额',
            'transaction_currency' => '交易币种',
            'outbinservice' => '服务费',
            'transaction_type' => '交易类型',
            'status' => '交易状态',

        ];
    }

}